package com.bsoft.exchange.service;

import com.alibaba.fastjson.JSONObject;
import com.bsoft.exchange.dao.his.SystemConfigMapper;
import com.bsoft.exchange.dao.his.YBServiceMapper;
import com.bsoft.exchange.domain.*;
import com.bsoft.exchange.param.DetailReport;
import com.bsoft.exchange.param.FeeSettlement;
import com.bsoft.exchange.param.SignParam;
import com.bsoft.exchange.pojo.OutResponse;
import com.bsoft.exchange.util.DateUtil;
import com.github.dozermapper.core.DozerBeanMapper;
import com.github.dozermapper.core.DozerBeanMapperBuilder;
import com.github.dozermapper.core.Mapper;
import com.github.dozermapper.spring.DozerBeanMapperFactoryBean;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by Lenovo on 2020/8/19.
 */
@Slf4j
@Component
public class YBService {

    @Resource
    Gson gson;

    @Autowired
    YBServiceMapper ybServiceMapper;

    @Autowired
    SystemConfigMapper systemConfigMapper;

    @Resource
    private RestTemplate restTemplate;

    private static final String url = "http://10.77.100.31:8001/miweb/mitrade.do";

    private Mapper mapper = DozerBeanMapperBuilder.buildDefault();



    public String getzqh(){
        String getzhouqihao = ybServiceMapper.getzhouqihao("1101");
        return getzhouqihao;
    }

    /**
     * 医保签到
     * @param ygdm 医构代码
     * @param czbh 操作编号
     * @return 周期号
     */
    public String doQuerySFQD(String ygdm, String czbh) {
        String YYJYLSH = getYylsh(ygdm);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("9100^").append("1101").append("^").append(czbh).append("^^")
                .append(YYJYLSH).append("^0000^|||@^1^");
        JSONObject json = param(ygdm, stringBuilder);
        log.info("医保入参：" + json);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
        log.info("医保返回：" + responseEntity.getBody());
        JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
        String data = jsonObject.get("data").toString();
        String[] arr = data.split("\\^");
        String zqh = StringUtils.substring(arr[2], 0, arr[2].length() - 1);
        ybServiceMapper.save(ygdm, zqh, new Date(), null);
        return zqh;
//        }
    }

    /**
     * 签退
     *
     * @param ygdm 医疗机构编号
     * @param czbh 操作员编号
     * @return 是否退签成功
     */
    public boolean signOut(String ygdm, String czbh) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        boolean flag = true;
        if (StringUtils.isNotBlank(zqh)) {
            String YYJYLSH = getYylsh(ygdm);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("9110^").append("1101").append("^").append(czbh)
                    .append("^").append(zqh).append("^").append(YYJYLSH).append("^0000^|||@^1^");
            JSONObject json = param(ygdm, stringBuilder);
            log.info("医保入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                ybServiceMapper.update(ygdm, zqh, new Date());
            } else {
                flag = false;
            }
        } else {
            flag = false;
        }
        return flag;
    }

    /**
     * 读卡获取用户信息
     *
     * @param ygdm    医疗机构代码
     * @param czbh    操作员编号
     * @param cardNum 医保卡号
     * @return 用户信息
     */
    public PersonalInfoDomain getPersonalInfoDomain(String ygdm, String czbh, String cardNum) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        PersonalInfoDomain personalInfoDomain = null;
        if (StringUtils.isNotBlank(zqh)) {
            String YYJYLSH = getYylsh(ygdm);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2100^").append(ygdm).append("^").append(czbh)
                    .append("^").append(zqh).append("^").append(YYJYLSH).append("^0000^|")
                    .append(cardNum).append("||@^1^");
            JSONObject json = param(ygdm, stringBuilder);
            log.info("医保入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                String data = jsonObject.get("data").toString();
                String[] datas = data.split("\\^");
                String info = datas[2];
                String[] infoArr = info.split("\\|");
                personalInfoDomain = new PersonalInfoDomain();
                Class<PersonalInfoDomain> clazz = PersonalInfoDomain.class;
                Field[] declaredFields = clazz.getDeclaredFields();
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    field.setAccessible(true);
                    try {
                        field.set(personalInfoDomain, infoArr[i]);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        return null;
                    }
                }
            }
        }
        return personalInfoDomain;
    }

    /**
     * 住院/就诊登记
     *
     * @param signParam 参数
     * @return 登记信息
     */
    public SignResponse sign(SignParam signParam) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        SignResponse signResponse = null;
        SignResponseDomain signResponseDomain = null;
        String mzlsh = getMzlsh("WX");
        if (StringUtils.isNotBlank(zqh)) {
            String yyjylsh = getYylsh("1101");
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2210^").append("1101").append("^")
                    .append(signParam.getCzbm()).append("^").append(zqh).append("^")
                    .append(yyjylsh).append("^0000^|").append(signParam.getCardNum())
                    .append("||@").append(mzlsh).append("|").append(signParam.getMedicalCategory())
                    .append("|").append(signParam.getRegistrationDate()).append("|").append(signParam.getDiagnosticDiseaseCode() == null ?"":signParam.getDiagnosticDiseaseCode())
                    .append("|").append(signParam.getName()).append("|").append(signParam.getMedicalRecordInformation()).append("|")
                    .append(signParam.getDepartmentName()).append("|").append(signParam.getBedNum()).append("|").append(signParam.getDoctorCode())
                    .append("|").append(signParam.getDoctorName()).append("|").append(signParam.getRegistrationFee()).append("|")
                    .append(signParam.getInspectionFees()).append("|").append("900001").append("|").append(signParam.getSpare01())
                    .append("|").append(signParam.getSpare02()).append("|").append(signParam.getSpare03()).append("|").append(signParam.getHospitalNum())
                    .append("|").append(signParam.getWard()).append("|").append("^1^");
            JSONObject json = param(signParam.getYgdm(), stringBuilder);
            log.info("医保登记入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保登记返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            Class<SignResponseDomain> clazz = SignResponseDomain.class;
            signResponseDomain = new SignResponseDomain();

            if (code == 0) {
                String data = jsonObject.get("data").toString();
                String[] strings = data.split("\\^");
                String result = strings[2];
                String[] split = result.split("\\|");
                Field[] declaredFields = clazz.getDeclaredFields();
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    field.setAccessible(true);
                    try {
                        String str = split[i];
                        if(str.startsWith(".")){
                            str = "0" + str;
                        }
                        field.set(signResponseDomain, str);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                signResponse = mapper.map(signResponseDomain, SignResponse.class);
                signResponse.setMzlsh(mzlsh);
                signResponse.setYyjylsh(yyjylsh);
                signResponse.setZqh(zqh);
                signResponse.setJyls(strings[0]);
            }
        }

        return signResponse;
    }


    /**
     * 登记/挂号撤销
     *
     * @param serialNum 流水号
     * @param czbm      操作员编码
     * @param ygdm      医疗机构代码
     * @param cardNum   医保卡号
     * @return 是否成功
     */
    public OutResponse out(String serialNum, String czbm, String ygdm, String cardNum) {
        OutResponse outResponse = null;
        String zqh = ybServiceMapper.getzhouqihao("1101");
        if (StringUtils.isNotBlank(zqh)) {
            String yyjylsh = getYylsh("1101");
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2240^").append(ygdm).append("^")
                    .append(czbm).append("^").append(zqh).append("^")
                    .append(yyjylsh).append("^").append("0000")
                    .append("^").append("|").append(cardNum).append("||@")
                    .append(serialNum).append("|").append(czbm).append("|")
                    .append("^1^");
            JSONObject json = param(ygdm, stringBuilder);
            log.info("医保登记撤销入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保登记撤销返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                outResponse = new OutResponse();
                outResponse.setFsfjylsh(yyjylsh);
                String data = jsonObject.get("data").toString();
                String[] strings = data.split("\\^");
                outResponse.setZxjylsh(strings[0]);
                return outResponse;
            }
        }
        return outResponse;
    }

    /**
     * 4.3.2.6处方明细上报
     *
     * @param detailReport 入参
     * @return 上报结果
     */
    public DetailReportResponse detailReport(DetailReport detailReport) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        log.info("======= 周期号为: {} ======",zqh);
        DetailReportResponse detailReportResponse = null;
        if (StringUtils.isNotBlank(zqh)) {
            String yyjylsh = getYylsh("1101");
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2310^").append("1101").append("^")
                    .append("900001").append("^").append(zqh).append("^")
                    .append(yyjylsh).append("^").append("0000")
                    .append("^").append("|").append(detailReport.getCardNum()).append("||@")
                    .append(detailReport.getSerialNum()).append("|").append(detailReport.getItemCategory()).append("|")
                    .append(detailReport.getCostCategory()).append("|").append(detailReport.getPrescriptionNumber()).append("|")
                    .append(detailReport.getPrescriptionDate()).append("|").append(detailReport.getInternalCode()).append("|")
                    .append(detailReport.getCenterCode()).append("|").append(detailReport.getItemName()).append("|")
                    .append(detailReport.getUnitPrice()).append("|").append(detailReport.getQuantity()).append("|")
                    .append(detailReport.getDosage()).append("|").append(detailReport.getSpecification()).append("|")
                    .append(detailReport.getDosage()).append("|").append(detailReport.getFrequency()).append("|")
                    .append(detailReport.getDoctorName()).append("|").append(detailReport.getPrescribingPhysician()).append("|")
                    .append(detailReport.getUsage()).append("|").append(detailReport.getUnit()).append("|")
                    .append(detailReport.getDivisionName()).append("|").append(detailReport.getExecutionDays()).append("|")
                    .append(detailReport.getSign()).append("|").append(detailReport.getManager()).append("|")
                    .append(detailReport.getSpare01()).append("|").append(detailReport.getSpare02()).append("|")
                    .append(detailReport.getSpare03()).append("|").append("^1^");
            JSONObject json = param1(detailReport.getYgdm(), stringBuilder);
            log.info("医保处方上传入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保处方上传返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                String data = jsonObject.get("data").toString();
                String[] strings = data.split("\\^");
                String result = strings[2];
                String[] split = result.split("\\|");
                detailReportResponse = new DetailReportResponse();
                Class<DetailReportResponse> clazz = DetailReportResponse.class;
                Field[] declaredFields = clazz.getDeclaredFields();
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    field.setAccessible(true);
                    try {
                        field.set(detailReportResponse, split[i]);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }

        }
        return detailReportResponse;
    }


    public boolean detailReportChancel(String mzlsh,String jylsh,String jbr,String ybkh){
        String zqh = ybServiceMapper.getzhouqihao("1101");
        String yylsh = getYylsh("1101");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("2320^").append("1101^").append("01^")
                .append(zqh).append("^").append(yylsh).append("^0000^|").append(ybkh)
                .append("||@").append(mzlsh).append("||").append(jbr).append("|^1^");
        JSONObject json = param("1101",stringBuilder);
        log.info("医保处方上传撤销入参：" + json);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
        log.info("医保处方上传撤销返回：" + responseEntity.getBody());
        JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
        double code = (double) jsonObject.get("code");
        if (code == 0) {
            return true;
        }
        return false;
    }

    /**
     * 预结算
     *
     * @param feeSettlement 预结算参数
     * @return 预结算返回参数
     */
    public FeeSettlementResponse preSettlement(FeeSettlement feeSettlement) {
       String zqh = ybServiceMapper.getzhouqihao("1101");
        FeeSettlementResponse feeSettlementResponse = null;
        String yylsh = getYylsh("1101");
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("2420^").append("1101").append("^01^")
                .append(zqh).append("^").append(yylsh).append("^0000^|").append(feeSettlement.getCardNum())
                .append("||@").append(feeSettlement.getSerialNum()).append("|").append(feeSettlement.getDjh()).append("|")
                .append(feeSettlement.getMedicalCategory())
                .append("|").append(feeSettlement.getSettlementDate()).append("|").append(feeSettlement.getDischargeDate())
                .append("|").append(feeSettlement.getReason()).append("|").append(feeSettlement.getDiseaseCode()).append("|")
                .append(feeSettlement.getDiseaseName()).append("|").append(feeSettlement.getReimbursementCategory()).append("|")
                .append(feeSettlement.getUseLogo()).append("|").append(feeSettlement.getSettlementSign()).append("|")
                .append(feeSettlement.getManager()).append("|").append(feeSettlement.getSign()).append("|")
                .append(feeSettlement.getIdentification()).append("|").append(feeSettlement.getSpare01()).append("|")
                .append(feeSettlement.getSpare02()).append("|").append(feeSettlement.getSpare03()).append("|")
                .append(feeSettlement.getSpare04()).append("|^1^");
        JSONObject json = param(feeSettlement.getYgdm(), stringBuilder);
        log.info("医保预结算入参：" + json);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
        log.info("医保预结算返回：" + responseEntity.getBody());
        JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
        double code = (double) jsonObject.get("code");
        if (code == 0) {
            String data = jsonObject.get("data").toString();
            String[] strings = data.split("\\^");
            String result = strings[2];
            String[] split = result.split("\\|");
            feeSettlementResponse = new FeeSettlementResponse();
            Class<FeeSettlementResponse> clazz = FeeSettlementResponse.class;
            Field[] declaredFields = clazz.getDeclaredFields();
            for (int i = 0; i < declaredFields.length - 3; i++) {
                Field field = declaredFields[i];
                field.setAccessible(true);
                try {
                    field.set(feeSettlementResponse, split[i]);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            feeSettlementResponse.setYwzqh(zqh);
            feeSettlementResponse.setJylsh(yylsh);
            feeSettlementResponse.setYbjylsh(strings[0]);
        }
        return feeSettlementResponse;
    }

    /**
     * 费用结算
     *
     * @param feeSettlement 结算参数
     * @return 结算返回数据
     */
    public FeeSettlementResponse feeSettlement(FeeSettlement feeSettlement) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        FeeSettlementResponse feeSettlementResponse = null;
        if (StringUtils.isNotBlank(zqh)) {
            String yylsh = getYylsh(feeSettlement.getYgdm());
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2410^").append("1101").append("^01^")
                    .append(zqh).append("^").append(yylsh).append("^0000^|").append(feeSettlement.getCardNum())
                    .append("||@").append(feeSettlement.getSerialNum()).append("|").append(feeSettlement.getMedicalCategory())
                    .append("|").append(feeSettlement.getSettlementDate()).append("|").append(feeSettlement.getDischargeDate())
                    .append("|").append(feeSettlement.getReason()).append("|").append(feeSettlement.getDiseaseCode()).append("|")
                    .append(feeSettlement.getDiseaseName()).append("|").append(feeSettlement.getReimbursementCategory()).append("|")
                    .append(feeSettlement.getUseLogo()).append("|").append(feeSettlement.getSettlementSign()).append("|")
                    .append(feeSettlement.getManager()).append("|").append(feeSettlement.getSign()).append("|")
                    .append(feeSettlement.getIdentification()).append("|").append(feeSettlement.getSpare01()).append("|")
                    .append(feeSettlement.getSpare02()).append("|").append(feeSettlement.getSpare03()).append("|")
                    .append(feeSettlement.getSpare04()).append("|^1^");
            JSONObject json = param(feeSettlement.getYgdm(), stringBuilder);
            log.info("医保结算入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保结算返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                String data = jsonObject.get("data").toString();
                String[] strings = data.split("\\^");
                String result = strings[2];
                String[] split = result.split("\\|");
                feeSettlementResponse = new FeeSettlementResponse();
                Class<FeeSettlementResponse> clazz = FeeSettlementResponse.class;
                Field[] declaredFields = clazz.getDeclaredFields();
                for (int i = 0; i < declaredFields.length; i++) {
                    Field field = declaredFields[i];
                    field.setAccessible(true);
                    try {
                        field.set(feeSettlementResponse, split[i]);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
                feeSettlementResponse.setYwzqh(zqh);
                feeSettlementResponse.setYbjylsh(yylsh);
                feeSettlementResponse.setJylsh(strings[0]);
            }
        }
        return feeSettlementResponse;
    }

    /**
     * 结算撤销
     *
     * @param feeSettlement 结算撤销参数
     * @return 是否撤销成功
     */
    public boolean feeSettlementCancellation(FeeSettlement feeSettlement) {
        String zqh = ybServiceMapper.getzhouqihao("1101");
        boolean flag = false;
        if (StringUtils.isNotBlank(zqh)) {
            String yylsh = getYylsh(feeSettlement.getYgdm());
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("2430^").append(feeSettlement.getYgdm()).append("^01^")
                    .append(zqh).append("^").append(yylsh).append("^0000^|").append(feeSettlement.getCardNum())
                    .append("||@").append(feeSettlement.getSerialNum()).append("|").append(feeSettlement.getMedicalCategory())
                    .append("|").append(feeSettlement.getSettlementDate()).append("|").append(feeSettlement.getDischargeDate())
                    .append("|").append(feeSettlement.getReason()).append("|").append(feeSettlement.getDiseaseCode()).append("|")
                    .append(feeSettlement.getDiseaseName()).append("|").append(feeSettlement.getReimbursementCategory()).append("|")
                    .append(feeSettlement.getUseLogo()).append("|").append(feeSettlement.getSettlementSign()).append("|")
                    .append(feeSettlement.getManager()).append("|").append(feeSettlement.getSign()).append("|")
                    .append(feeSettlement.getIdentification()).append("|").append(feeSettlement.getSpare01()).append("|")
                    .append(feeSettlement.getSpare02()).append("|").append(feeSettlement.getSpare03()).append("|")
                    .append(feeSettlement.getSpare04()).append("|^1^");
            JSONObject json = param(feeSettlement.getYgdm(), stringBuilder);
            log.info("医保结算撤销入参：" + json);
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, json, String.class);
            log.info("医保结算撤销返回：" + responseEntity.getBody());
            JSONObject jsonObject = gson.fromJson(responseEntity.getBody(), JSONObject.class);
            double code = (double) jsonObject.get("code");
            if (code == 0) {
                flag = true;
            }
        }
        return flag;
    }

    /**
     * 封装json参数
     *
     * @param ygdm          医疗机构代码
     * @param stringBuilder 线下医保交易参数字符串
     */
    private JSONObject param(String ygdm, StringBuilder stringBuilder) {
        String s = stringBuilder.toString();
        String replace = StringUtils.replace(s, "null", "-");
        JSONObject json = new JSONObject();
        json.put("hoscode", "1101");
        json.put("data", replace);
        return json;
    }

    private JSONObject param1(String ygdm, StringBuilder stringBuilder){
        String s = stringBuilder.toString();
        String replace = StringUtils.replace(s, "null", "");
        JSONObject json = new JSONObject();
        json.put("hoscode", "1101");
        json.put("data", replace);
        return json;
    }


    /**
     * @description 获取医院交易流水号
     */
    public String getYylsh(String yybh) {
        StringBuffer lsh = new StringBuffer();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        lsh.append(sdf.format(new Date())).append("-").append(yybh)
                .append("-").append(RandomStringUtils.random(4, false, true));
        System.out.println(lsh.toString());
        return lsh.toString();
    }

    private String getMzlsh(String start){
        StringBuilder stringBuilder = new StringBuilder();
        double random = Math.random()*1000;
        stringBuilder.append(start).append(new Date().getTime());
//        .append(random);
        return  stringBuilder.toString();
    }

    public static void main(String[] args) {
        YBService ybService = new YBService();
        String zqh = ybService.doQuerySFQD("1101", "100000");
//        boolean b = ybService.out(zqh, "WX1605786536979", "100000", "1101", "JSJ073819527");
//        System.out.println(b);
    }


}
